using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;

namespace DotNetCRM.Core.ExtensionMethods
{
    public static class CollectionExtensions
    {
        public static ICollection<T> AsCollection<T>(this IEnumerable<T> collection)
        {
            return (ICollection<T>) collection;
        }

        public static void CheckIfEmpty<T>(this ICollection<T> collection, string message)
        {
            if (collection.Count == 0)
            {
                throw new InvalidOperationException(message);
            }
        }

        public static void ForEach<T>(this IEnumerable<T> collection, Action<T> del)
        {
            foreach(T t in collection)
            {
                del(t);
            }
        }

        public static void AddRange<T>(this IList<T> collection, IEnumerable<T> toAdd)
        {
            if (toAdd == null || !toAdd.Any()) return;

            BindingList<T> bl = collection as BindingList<T>;
            if (bl != null)
                bl.RaiseListChangedEvents = false;
            foreach (T t in toAdd)
            {
                collection.Add(t);
            }
            if (bl != null)
            {
                bl.RaiseListChangedEvents = true;
                bl.ResetBindings();
            }
        }

        public static IEnumerable<TItem> Common<TOwner, TItem>(this IEnumerable<TOwner> collection, Func<TOwner, IEnumerable<TItem>> expression)
        {
            return from o in collection
                   from i in expression(o)
                   group i by i
                   into itemGroup
                       where itemGroup.Count() == collection.Count()
                       select itemGroup.Key;
        }

        public static IEnumerable<TOwner> Duplicates<TOwner>(this IEnumerable<TOwner> collection, Func<TOwner, object> groupByExpression)
        {
            return (from o in collection
                    group o by groupByExpression(o)
                    into g
                        where g.Count() > 1
                        select g).SelectMany(a => a);
        }

        public static List<TKey> GetKeys<TKey, TItem>(this IEnumerable<KeyValuePair<TKey, TItem>> collection, TItem item)
        {
            return collection.Where(x => Equals(x.Value, item)).Select(x => x.Key).ToList();
        }

        public static IEnumerable Isolate(this IEnumerable list)
        {
            return new IteratorIsolate(list);
        }

    }
}